package com.whut.manage.service;

import com.alibaba.fastjson.JSON;


import com.alibaba.fastjson.JSONObject;
import com.aliyun.hitsdb.client.HiTSDB;
import com.aliyun.hitsdb.client.exception.http.HttpUnknowStatusException;
import com.aliyun.hitsdb.client.value.request.Query;
import com.aliyun.hitsdb.client.value.request.SubQuery;
import com.aliyun.hitsdb.client.value.response.QueryResult;
import com.aliyun.hitsdb.client.value.response.QueryResultDpsSerializer;
import com.aliyun.hitsdb.client.value.type.Aggregator;
import com.whut.manage.utils.TSDBUtil;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.message.MapMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sound.midi.Soundbank;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author WZH
 * @create 2021-03-09 11:45
 * @desc 历史数据查询
 **/
@Log4j2
@Service
public class HistoryDataQueryService {

    /**
     *通过Metric字段查询历史一段时间内的数据
     * @param metric
     * @param startTime
     * @param endTime
     * @return {@link String}
     * @author WZH
     * @date 2021/3/9 12:06
     */
    public Object findByMetric(String metric, Date startTime, Date endTime,String deviceNametag) {
        HiTSDB tsdb = TSDBUtil.getHiTSDB();
        // 查询一小时的数据
        Query query = Query.timeRange(startTime, endTime)
                .sub(SubQuery.metric( metric).aggregator(Aggregator.NONE).tag("deviceName",deviceNametag).build()).build();
        // 查询数据
        List<QueryResult> list = null;
        try {
            list = tsdb.query(query);
        } catch (HttpUnknowStatusException e) {
            log.error(e.getMessage());
        }
        QueryResult queryResult = list.get(0);
        String result = queryResult.toJSON();
        Object obj=JSON.parse(result);
        return obj;
    }



    /**
     *通过一个Metrics集合可以实现多个metric查询
     * @param metrics
     * @param startTime
     * @param endTime
     * @return {{@link Object}}
     * @author WZH
     * @date 2021/3/12 10:46
     */
    public Object findByMetrics(List<String> metrics, Date startTime, Date endTime,String deviceName)  {
        HiTSDB tsdb = TSDBUtil.getHiTSDB();
        //创建一个List来存放子查询
        List<SubQuery> subQueryList = new ArrayList<SubQuery>();
        for (String metric : metrics) {
            subQueryList.add(SubQuery.metric(metric).aggregator(Aggregator.NONE).tag("deviceName",deviceName).build());
        }
        //执行上诉List集合中的所有子查询
        Query query = Query.timeRange(startTime, endTime).sub(subQueryList).build();
        //格式化时间对象
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //创建一个json对象用于存放 timestamp value
        JSONObject metricJson = new JSONObject();
        List<QueryResult> queryList = tsdb.query(query);
        //遍历每一个选择的结果
        for (String metric : metrics) {
            //创建一个新的TreeMap用于存放排序后的key value值
            TreeMap<String, Object> stringObjectTreeMap = new TreeMap<>(new Comparator<String>() {
                @SneakyThrows
                @Override
                public int compare(String o1, String o2) {
                    Date parse1 = simpleDateFormat.parse(o1);
                    Date parse2 = simpleDateFormat.parse(o2);
                    long o1_long = parse1.getTime();
                    long o2_long = parse2.getTime();
                    if (o1_long < o2_long) {
                        return -1;
                    } else if (o1_long > o2_long) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            });
//        遍历每一个子查询的结果queryResult。一个子查询，因为tag有多个，所以会有多个queryResult
            for (QueryResult queryResult : queryList) {
                /*q
                ueryList中有多条记录，假如查询aShift和a_l，有6条记录，3条aShift和3条a_l的记录
                因此要确定当前循环的queryResult的metric字段名和metricList中的字段名一致
                免得造成 TreeMap中添加数据错乱
                */
                if (queryResult.getMetric().equals(metric) ) {
            /*创建一个新的LinkedHashMap用于存放格式化后的字符串形式的Key-Value值
            LinkedHashMap<String, Object> StringObjectMap = new LinkedHashMap<String, Object>();*/
                    LinkedHashMap<Long, Object> dps = queryResult.getDps();
                    //遍历dps时间序列集合，对dps中的时间戳格式化成"yyyy-MM-dd HH:mm:ss"形式
                    Set<Map.Entry<Long, Object>> entries = dps.entrySet();
                    for (Map.Entry<Long, Object> en : entries) {
                        String format_date = simpleDateFormat.format(new Date(en.getKey() * 1000));
                        stringObjectTreeMap.put(format_date, en.getValue());
                    }
                }
                    //将metric写入到json对象中
                    metricJson.put(metric, stringObjectTreeMap);
            }
        }
            return metricJson;
    }


    /**
     *通过一个Metrics集合可以实现多个metric查询
     * @param metrics
     * @param startTime
     * @param endTime
     * @return {{@link Object}}
     * @author WZH
     * @date 2021/3/12 10:46
     */
    public Object findByMetricsTest(List<String> metrics, Date startTime, Date endTime,String deviceName)  {
        HiTSDB tsdb = TSDBUtil.getHiTSDB();
        //创建一个List来存放子查询
        List<SubQuery> subQueryList = new ArrayList<SubQuery>();
        for (String metric : metrics) {
            subQueryList.add(SubQuery.metric(metric).aggregator(Aggregator.NONE).tag("deviceName",deviceName).build());
        }
        //执行上诉List集合中的所有子查询
        Query query = Query.timeRange(startTime, endTime).sub(subQueryList).build();
        //格式化时间对象
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //创建一个json对象用于存放 timestamp value
        JSONObject metricJson = new JSONObject();
        List<QueryResult> queryList = tsdb.query(query);
        //遍历每一个选择的结果
        for (String metric : metrics) {
            //创建一个新的TreeMap用于存放排序后的key value值
            TreeMap<String, Object> stringObjectTreeMap = new TreeMap<>(new Comparator<String>() {
                @SneakyThrows
                @Override
                public int compare(String o1, String o2) {
                    Date parse1 = simpleDateFormat.parse(o1);
                    Date parse2 = simpleDateFormat.parse(o2);
                    long o1_long = parse1.getTime();
                    long o2_long = parse2.getTime();
                    if (o1_long < o2_long) {
                        return -1;
                    } else if (o1_long > o2_long) {
                        return 1;
                    } else {
                        return 0;
                    }
                }
            });
//        遍历每一个子查询的结果queryResult。一个子查询，因为tag有多个，所以会有多个queryResult
            for (QueryResult queryResult : queryList) {
                /*q
                ueryList中有多条记录，假如查询aShift和a_l，有6条记录，3条aShift和3条a_l的记录
                因此要确定当前循环的queryResult的metric字段名和metricList中的字段名一致
                免得造成 TreeMap中添加数据错乱
                */
                if (queryResult.getMetric().equals(metric) ) {
            /*创建一个新的LinkedHashMap用于存放格式化后的字符串形式的Key-Value值
            LinkedHashMap<String, Object> StringObjectMap = new LinkedHashMap<String, Object>();*/
                    LinkedHashMap<Long, Object> dps = queryResult.getDps();
                    //遍历dps时间序列集合，对dps中的时间戳格式化成"yyyy-MM-dd HH:mm:ss"形式
                    Set<Map.Entry<Long, Object>> entries = dps.entrySet();
                    for (Map.Entry<Long, Object> en : entries) {
                        String format_date = simpleDateFormat.format(new Date(en.getKey() * 1000));
                        stringObjectTreeMap.put(format_date, en.getValue());
                    }
                }
                //将metric写入到json对象中
                metricJson.put(metric, stringObjectTreeMap);
            }
        }
        return metricJson;
    }



}

